﻿using System.Net;
using System.Text;
using Devonline.AspNetCore;
using Devonline.Core;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace Devonline.CloudService.Feige;

/// <summary>
/// 飞鸽云接口短信发送服务
/// </summary>
public class SmsService : ISmsService
{
    private readonly IHttpClientFactory _httpClientFactory;
    protected readonly ILogger<SmsService> _logger;
    protected readonly ISmsEndpoint _endpoint;
    public SmsService(ILogger<SmsService> logger, IHttpClientFactory httpClientFactory, ISmsEndpoint endpoint)
    {
        ArgumentNullException.ThrowIfNull(endpoint.Host);
        ArgumentNullException.ThrowIfNull(endpoint.AppId);
        ArgumentNullException.ThrowIfNull(endpoint.Secret);
        _logger = logger;
        _endpoint = endpoint;
        _httpClientFactory = httpClientFactory;
    }

    /// <summary>
    /// 飞鸽云接口发送短信
    /// </summary>
    /// <param name="model">短信内容数据模型</param>
    /// <returns></returns>
    public async Task SendAsync(ISmsModel model) => await SendAsync(model.SignName, model.TemplateCode, model.TemplateParam, model.PhoneNumbers!);
    /// <summary>
    /// 飞鸽云接口发送短信息
    /// </summary>
    /// <param name="signName">短信签名</param>
    /// <param name="templateCode">短信内容模板编号</param>
    /// <param name="templateParam">短信内容模板中的变量和值的集合</param>
    /// <param name="phoneNumbers">发送的手机号码</param>
    /// <returns></returns>
    public async Task SendAsync(string signName, string templateCode, Dictionary<string, string> templateParam, params string[] phoneNumbers)
    {
        if (!templateParam.Any())
        {
            throw new Exception("The feige sms service send message need template params!");
        }

        if (phoneNumbers is null || phoneNumbers.Length == 0)
        {
            throw new Exception("The feige sms service send message need phone number(s)!");
        }

        var smsModel = new FeigeSmsModel
        {
            ApiKey = _endpoint.AppId,
            Secret = _endpoint.Secret,
            PhoneNumbers = phoneNumbers.ToString(AppSettings.DEFAULT_OUTER_SPLITER),
            SignName = Convert.ToInt64(signName),
            TemplateCode = Convert.ToInt64(templateCode),
            Content = templateParam.Values.ToString("||"),
            SendTime = DateTime.Now.ToUnixTimeSeconds(),
        };

        var content = smsModel.ToJsonString();
        using var request = new HttpRequestMessage(System.Net.Http.HttpMethod.Post, _endpoint.Path);
        request.Version = HttpVersion.Version11;
        request.Content = new StringContent(content, Encoding.UTF8, new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType.Json));
        request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType.Json);

        _logger.LogInformation($"The feige sms service will send sms message to: {_endpoint.Path}, the request body: " + content);
        using var httpClient = _httpClientFactory.CreateClient(nameof(SmsService));
        using var response = await httpClient.SendAsync(request);
        var result = await response.Content.ReadAsStringAsync();

        if (!response.IsSuccessStatusCode)
        {
            throw new BadHttpRequestException($"飞鸽云短信请求失败, 详情: {result}");
        }

        if (string.IsNullOrWhiteSpace(result))
        {
            throw new BadHttpRequestException($"飞鸽云短信发生失败, 服务器未返回内容!");
        }

        _logger.LogInformation($"The feige sms service send message result: {result}");
        var smsResponse = result.ToJsonObject<FeigeSmsResponse>();
        if (smsResponse is null || smsResponse.Code != 0)
        {
            throw new BadHttpRequestException($"飞鸽云短信发生失败, 详情: {smsResponse?.Message}");
        }

        _logger.LogInformation("The feige sms service send message success!");
    }
}

/// <summary>
/// 发送短信验证码的服务
/// </summary>
public class SmsCaptchaService : SmsService, ISmsService, ISmsCaptchaService
{
    private readonly ISmsModel _smsModel;
    public SmsCaptchaService(ILogger<SmsService> logger, IHttpClientFactory httpClientFactory, ISmsEndpoint endpoint, ISmsModel smsModel) : base(logger, httpClientFactory, endpoint) => _smsModel = smsModel;

    /// <summary>
    /// 发送手机验证码, 短信验证码的模板变量名字固定为 : code
    /// </summary>
    /// <param name="phoneNumbers">发送的手机号码</param>
    /// <returns></returns>
    public async Task<string> SendCaptchaAsync(params string[] phoneNumbers)
    {
        var phoneNumberStrings = phoneNumbers.ToString<string>();
        var code = new Random(DateTime.Now.Millisecond).Next(100000, 999999).ToString();
        _logger.LogDebug($"The feige sms service will send captcha: {code} to {phoneNumberStrings}");
        await SendAsync(_smsModel.SignName, _smsModel.TemplateCode, new Dictionary<string, string> { { nameof(code), code } }, phoneNumbers);
        _logger.LogInformation($"The feige sms service send captcha: {code} to {phoneNumberStrings} success");
        return code;
    }
}